home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_kernel_source / FS / ATTR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  2.6 KB  |  104 lines

  1. /*
  2.  *  linux/fs/attr.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *  changes by Thomas Schoebel-Theuer
  6.  */
  7.  
  8. #include <linux/sched.h>
  9. #include <linux/mm.h>
  10. #include <linux/string.h>
  11.  
  12. /* Taken over from the old code... */
  13.  
  14. /* POSIX UID/GID verification for setting inode attributes. */
  15. int inode_change_ok(struct inode *inode, struct iattr *attr)
  16. {
  17.     int retval = -EPERM;
  18.     unsigned int ia_valid = attr->ia_valid;
  19.  
  20.     /* If force is set do it anyway. */
  21.     if (ia_valid & ATTR_FORCE)
  22.         goto fine;
  23.  
  24.     /* Make sure a caller can chown. */
  25.     if ((ia_valid & ATTR_UID) &&
  26.         (current->fsuid != inode->i_uid ||
  27.          attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
  28.         goto error;
  29.  
  30.     /* Make sure caller can chgrp. */
  31.     if ((ia_valid & ATTR_GID) &&
  32.         (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) &&
  33.         !capable(CAP_CHOWN))
  34.         goto error;
  35.  
  36.     /* Make sure a caller can chmod. */
  37.     if (ia_valid & ATTR_MODE) {
  38.         if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
  39.             goto error;
  40.         /* Also check the setgid bit! */
  41.         if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
  42.                 inode->i_gid) && !capable(CAP_FSETID))
  43.             attr->ia_mode &= ~S_ISGID;
  44.     }
  45.  
  46.     /* Check for setting the inode time. */
  47.     if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) {
  48.         if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
  49.             goto error;
  50.     }
  51. fine:
  52.     retval = 0;
  53. error:
  54.     return retval;
  55. }
  56.  
  57. void inode_setattr(struct inode * inode, struct iattr * attr)
  58. {
  59.     unsigned int ia_valid = attr->ia_valid;
  60.  
  61.     if (ia_valid & ATTR_UID)
  62.         inode->i_uid = attr->ia_uid;
  63.     if (ia_valid & ATTR_GID)
  64.         inode->i_gid = attr->ia_gid;
  65.     if (ia_valid & ATTR_SIZE)
  66.         inode->i_size = attr->ia_size;
  67.     if (ia_valid & ATTR_ATIME)
  68.         inode->i_atime = attr->ia_atime;
  69.     if (ia_valid & ATTR_MTIME)
  70.         inode->i_mtime = attr->ia_mtime;
  71.     if (ia_valid & ATTR_CTIME)
  72.         inode->i_ctime = attr->ia_ctime;
  73.     if (ia_valid & ATTR_MODE) {
  74.         inode->i_mode = attr->ia_mode;
  75.         if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
  76.             inode->i_mode &= ~S_ISGID;
  77.     }
  78.     mark_inode_dirty(inode);
  79. }
  80.  
  81. int notify_change(struct dentry * dentry, struct iattr * attr)
  82. {
  83.     struct inode *inode = dentry->d_inode;
  84.     int error;
  85.     time_t now = CURRENT_TIME;
  86.     unsigned int ia_valid = attr->ia_valid;
  87.  
  88.     attr->ia_ctime = now;
  89.     if (!(ia_valid & ATTR_ATIME_SET))
  90.         attr->ia_atime = now;
  91.     if (!(ia_valid & ATTR_MTIME_SET))
  92.         attr->ia_mtime = now;
  93.  
  94.     if (inode->i_sb && inode->i_sb->s_op &&
  95.         inode->i_sb->s_op->notify_change) 
  96.         error = inode->i_sb->s_op->notify_change(dentry, attr);
  97.     else {
  98.         error = inode_change_ok(inode, attr);
  99.         if (!error)
  100.             inode_setattr(inode, attr);
  101.     }
  102.     return error;
  103. }
  104.